class Game2048 {
  constructor() {
    // 尝试从localStorage加载保存的游戏状态
    const savedState = localStorage.getItem('gameState');
    if (savedState) {
      const state = JSON.parse(savedState);
      this.grid = state.grid;
      this.score = state.score;
      this.bestScore = state.bestScore;
    } else {
      this.grid = Array(4).fill().map(() => Array(4).fill(0));
      this.score = 0;
      this.bestScore = parseInt(localStorage.getItem('bestScore')) || 0;
    }

    this.animations = [];
    this.isAnimating = false;
    this.history = [];
    this.maxHistory = 5;

    if (!savedState) {
      this.init();
    } else {
      this.updateView();
      this.updateBestScore();
    }

    // 添加清理方法
    this.cleanup = () => {
      this.saveGameState(); // 在清理前保存游戏状态
      this.history = [];
      this.animations = [];
      this.grid = null;
      document.removeEventListener('keydown', handleKeyPress);
      document.removeEventListener('touchstart', handleTouchStart);
      document.removeEventListener('touchmove', handleTouchMove);
      document.removeEventListener('touchend', handleTouchEnd);
      document.removeEventListener('gesturestart', handleGestureStart);
    };
  }

  init() {
    // 初始化游戏时添加两个数字
    this.addNewNumber();
    this.addNewNumber();
    this.updateView();
    this.updateBestScore();
  }

  updateBestScore() {
    if (this.score > this.bestScore) {
      this.bestScore = this.score;
      localStorage.setItem('bestScore', this.bestScore);
    }
  }

  addNewNumber() {
    const emptyCells = [];
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        if (this.grid[i][j] === 0) {
          emptyCells.push({ x: i, y: j });
        }
      }
    }
    if (emptyCells.length > 0) {
      const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
      this.grid[randomCell.x][randomCell.y] = Math.random() < 0.9 ? 2 : 4;
      this.animations.push({
        type: 'appear',
        x: randomCell.x,
        y: randomCell.y,
        value: this.grid[randomCell.x][randomCell.y]
      });
    }
  }

  updateView() {
    // 获取所有网格单元格
    const cells = document.querySelectorAll('.grid-cell');

    // 清除所有动画类和样式
    cells.forEach(cell => {
      cell.classList.remove('new-tile', 'merged-tile', 'moving');
      cell.style.transform = '';
      cell.style.transition = '';
      const span = cell.querySelector('span');
      if (span) {
        span.style.transform = '';
        span.style.transition = '';
      }
    });

    // 应用新的动画
    this.animations.forEach(animation => {
      const cell = document.getElementById(`cell-${animation.x}-${animation.y}`);
      if (!cell) return; // 添加安全检查

      const span = cell.querySelector('span');
      if (animation.type === 'appear') {
        cell.classList.add('new-tile');
      } else if (animation.type === 'merge') {
        cell.classList.add('merged-tile');
      } else if (animation.type === 'move') {
        cell.classList.add('moving');
        if (span) {
          span.style.transform = `translate(${animation.dx}px, ${animation.dy}px)`;
          span.style.transition = 'transform 0.15s ease-in-out';
        }
      }
    });

    // 更新网格显示
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        const cell = document.getElementById(`cell-${i}-${j}`);
        if (!cell) continue; // 添加安全检查

        const span = cell.querySelector('span');
        const value = this.grid[i][j];
        if (span) {
          span.textContent = value || '';
        }
        cell.setAttribute('data-value', value);
      }
    }

    const scoreElement = document.getElementById('score');
    const bestScoreElement = document.getElementById('best-score');

    if (scoreElement) scoreElement.textContent = this.score;
    if (bestScoreElement) bestScoreElement.textContent = this.bestScore;

    // 清除动画队列
    this.animations = [];
  }

  // 保存当前状态到历史记录
  saveState() {
    const state = {
      grid: JSON.parse(JSON.stringify(this.grid)), // 深拷贝网格
      score: this.score
    };
    this.history.push(state);
    if (this.history.length > this.maxHistory) {
      this.history.shift(); // 如果超过最大历史记录数，删除最早的记录
    }
  }

  // 撤销到上一步
  undo() {
    if (this.history.length === 0 || this.isAnimating) return;

    const lastState = this.history.pop();
    this.grid = lastState.grid;
    this.score = lastState.score;
    this.updateView();
  }

  // 添加保存游戏状态的方法
  saveGameState() {
    const gameState = {
      grid: this.grid,
      score: this.score,
      bestScore: this.bestScore
    };
    localStorage.setItem('gameState', JSON.stringify(gameState));
  }

  move(direction) {
    if (this.isAnimating) return;

    this.isAnimating = true;
    let moved = false;

    this.saveState();

    switch (direction) {
      case 'up':
        moved = this.moveUp();
        break;
      case 'down':
        moved = this.moveDown();
        break;
      case 'left':
        moved = this.moveLeft();
        break;
      case 'right':
        moved = this.moveRight();
        break;
    }

    if (moved) {
      this.updateView();
      setTimeout(() => {
        this.addNewNumber();
        this.updateView();
        this.updateBestScore();
        this.saveGameState(); // 每次移动后立即保存
        if (this.isGameOver()) {
          setTimeout(() => {
            alert(`游戏结束！\n当前得分：${this.score}\n最高分：${this.bestScore}`);
            localStorage.removeItem('gameState');
          }, 300);
        }
        this.isAnimating = false;
      }, 150);
    } else {
      this.history.pop();
      this.isAnimating = false;
    }
  }

  moveLeft() {
    let moved = false;
    for (let i = 0; i < 4; i++) {
      const oldRow = [...this.grid[i]];
      let row = this.grid[i].filter(x => x !== 0);
      let merged = Array(row.length).fill(false); // 添加标记数组

      // 合并相同的数字
      for (let j = 0; j < row.length - 1; j++) {
        if (!merged[j] && !merged[j + 1] && row[j] === row[j + 1]) { // 检查是否已经合并
          row[j] *= 2;
          this.score += row[j];
          row.splice(j + 1, 1);
          merged[j] = true; // 标记已合并
          merged.splice(j + 1, 1); // 更新标记数组
          moved = true;
          this.animations.push({
            type: 'merge',
            x: i,
            y: j,
            value: row[j]
          });
        }
      }

      // 填充0
      const newRow = row.concat(Array(4 - row.length).fill(0));

      // 检查是否有移动
      if (JSON.stringify(oldRow) !== JSON.stringify(newRow)) {
        moved = true;
        // 添加移动动画
        for (let j = 0; j < 4; j++) {
          if (oldRow[j] !== 0 && oldRow[j] !== newRow[j]) {
            const oldIndex = oldRow.indexOf(oldRow[j]);
            const newIndex = newRow.indexOf(oldRow[j]);
            if (oldIndex !== newIndex) {
              this.animations.push({
                type: 'move',
                x: i,
                y: j,
                dx: (newIndex - oldIndex) * 115,
                dy: 0
              });
            }
          }
        }
      }

      this.grid[i] = newRow;
    }
    return moved;
  }

  moveRight() {
    let moved = false;
    for (let i = 0; i < 4; i++) {
      const oldRow = [...this.grid[i]];
      let row = this.grid[i].filter(x => x !== 0);
      let merged = Array(row.length).fill(false); // 添加标记数组

      // 合并相同的数字
      for (let j = row.length - 1; j > 0; j--) {
        if (!merged[j] && !merged[j - 1] && row[j] === row[j - 1]) { // 检查是否已经合并
          row[j] *= 2;
          this.score += row[j];
          row.splice(j - 1, 1);
          merged[j - 1] = true; // 标记已合并
          merged.splice(j - 1, 1); // 更新标记数组
          moved = true;
          this.animations.push({
            type: 'merge',
            x: i,
            y: 3 - (row.length - j),
            value: row[j]
          });
        }
      }

      // 填充0
      const newRow = Array(4 - row.length).fill(0).concat(row);

      // 检查是否有移动
      if (JSON.stringify(oldRow) !== JSON.stringify(newRow)) {
        moved = true;
        // 添加移动动画
        for (let j = 0; j < 4; j++) {
          if (oldRow[j] !== 0 && oldRow[j] !== newRow[j]) {
            const oldIndex = oldRow.indexOf(oldRow[j]);
            const newIndex = newRow.indexOf(oldRow[j]);
            if (oldIndex !== newIndex) {
              this.animations.push({
                type: 'move',
                x: i,
                y: j,
                dx: (newIndex - oldIndex) * 115,
                dy: 0
              });
            }
          }
        }
      }

      this.grid[i] = newRow;
    }
    return moved;
  }

  moveUp() {
    let moved = false;
    for (let j = 0; j < 4; j++) {
      const oldColumn = this.grid.map(row => row[j]);
      let column = oldColumn.filter(x => x !== 0);
      let merged = Array(column.length).fill(false); // 添加标记数组

      // 合并相同的数字
      for (let i = 0; i < column.length - 1; i++) {
        if (!merged[i] && !merged[i + 1] && column[i] === column[i + 1]) { // 检查是否已经合并
          column[i] *= 2;
          this.score += column[i];
          column.splice(i + 1, 1);
          merged[i] = true; // 标记已合并
          merged.splice(i + 1, 1); // 更新标记数组
          moved = true;
          this.animations.push({
            type: 'merge',
            x: i,
            y: j,
            value: column[i]
          });
        }
      }

      // 填充0
      const newColumn = column.concat(Array(4 - column.length).fill(0));

      // 检查是否有移动
      if (JSON.stringify(oldColumn) !== JSON.stringify(newColumn)) {
        moved = true;
        // 添加移动动画
        for (let i = 0; i < 4; i++) {
          if (oldColumn[i] !== 0 && oldColumn[i] !== newColumn[i]) {
            const oldIndex = oldColumn.indexOf(oldColumn[i]);
            const newIndex = newColumn.indexOf(oldColumn[i]);
            if (oldIndex !== newIndex) {
              this.animations.push({
                type: 'move',
                x: i,
                y: j,
                dx: 0,
                dy: (newIndex - oldIndex) * 115
              });
            }
          }
        }
      }

      // 更新网格
      for (let i = 0; i < 4; i++) {
        this.grid[i][j] = newColumn[i];
      }
    }
    return moved;
  }

  moveDown() {
    let moved = false;
    for (let j = 0; j < 4; j++) {
      const oldColumn = this.grid.map(row => row[j]);
      let column = oldColumn.filter(x => x !== 0);
      let merged = Array(column.length).fill(false); // 添加标记数组

      // 合并相同的数字
      for (let i = column.length - 1; i > 0; i--) {
        if (!merged[i] && !merged[i - 1] && column[i] === column[i - 1]) { // 检查是否已经合并
          column[i] *= 2;
          this.score += column[i];
          column.splice(i - 1, 1);
          merged[i - 1] = true; // 标记已合并
          merged.splice(i - 1, 1); // 更新标记数组
          moved = true;
          this.animations.push({
            type: 'merge',
            x: 3 - (column.length - i),
            y: j,
            value: column[i]
          });
        }
      }

      // 填充0
      const newColumn = Array(4 - column.length).fill(0).concat(column);

      // 检查是否有移动
      if (JSON.stringify(oldColumn) !== JSON.stringify(newColumn)) {
        moved = true;
        // 添加移动动画
        for (let i = 0; i < 4; i++) {
          if (oldColumn[i] !== 0 && oldColumn[i] !== newColumn[i]) {
            const oldIndex = oldColumn.indexOf(oldColumn[i]);
            const newIndex = newColumn.indexOf(oldColumn[i]);
            if (oldIndex !== newIndex) {
              this.animations.push({
                type: 'move',
                x: i,
                y: j,
                dx: 0,
                dy: (newIndex - oldIndex) * 115
              });
            }
          }
        }
      }

      // 更新网格
      for (let i = 0; i < 4; i++) {
        this.grid[i][j] = newColumn[i];
      }
    }
    return moved;
  }

  isGameOver() {
    // 检查是否有空格
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        if (this.grid[i][j] === 0) return false;
      }
    }

    // 检查是否有相邻的相同数字
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        if (j < 3 && this.grid[i][j] === this.grid[i][j + 1]) return false;
        if (i < 3 && this.grid[i][j] === this.grid[i + 1][j]) return false;
      }
    }

    return true;
  }
}

let game;

function newGame() {
  if (game) {
    game.cleanup();
  }
  localStorage.removeItem('gameState'); // 开始新游戏时清除保存的状态
  game = new Game2048();
}

// 修改键盘事件监听
document.addEventListener('keydown', handleKeyPress);

function handleKeyPress(event) {
  if (!game) return;

  // 阻止方向键滚动页面
  if (event.key.startsWith('Arrow')) {
    event.preventDefault();
  }

  switch (event.key) {
    case 'ArrowUp':
    case 'w':
    case 'W':
      game.move('up');
      break;
    case 'ArrowDown':
    case 's':
    case 'S':
      game.move('down');
      break;
    case 'ArrowLeft':
    case 'a':
    case 'A':
      game.move('left');
      break;
    case 'ArrowRight':
    case 'd':
    case 'D':
      game.move('right');
      break;
    case 'z':
    case 'Z':
      if (event.ctrlKey || event.metaKey) { // Ctrl+Z 或 Command+Z
        game.undo();
        event.preventDefault();
      }
      break;
  }
}

// 添加触摸事件处理
let touchStartX = 0;
let touchStartY = 0;
let touchStartTime = 0;
const minSwipeDistance = 30; // 降低最小滑动距离
const maxSwipeTime = 300; // 最大滑动时间（毫秒）

// 将触摸事件处理函数提取出来，方便移除监听器
function handleTouchStart(event) {
  if (!game) return;
  touchStartX = event.touches[0].clientX;
  touchStartY = event.touches[0].clientY;
  touchStartTime = Date.now();
  event.preventDefault();
}

function handleTouchMove(event) {
  event.preventDefault();
}

function handleTouchEnd(event) {
  if (!game) return;
  const touchEndX = event.changedTouches[0].clientX;
  const touchEndY = event.changedTouches[0].clientY;
  const touchEndTime = Date.now();

  if (touchEndTime - touchStartTime > maxSwipeTime) {
    return;
  }

  const deltaX = touchEndX - touchStartX;
  const deltaY = touchEndY - touchStartY;

  if (Math.abs(deltaX) < minSwipeDistance && Math.abs(deltaY) < minSwipeDistance) {
    return;
  }

  if (Math.abs(deltaX) > Math.abs(deltaY)) {
    if (deltaX > 0) {
      game.move('right');
    } else {
      game.move('left');
    }
  } else {
    if (deltaY > 0) {
      game.move('down');
    } else {
      game.move('up');
    }
  }
}

function handleGestureStart(event) {
  event.preventDefault();
}

// 添加页面卸载时的清理
window.addEventListener('unload', () => {
  if (game) {
    game.cleanup();
  }
});

// 初始化游戏
window.addEventListener('DOMContentLoaded', () => {
  newGame();
});

// 移除原有的事件监听器绑定
document.removeEventListener('touchstart', handleTouchStart);
document.removeEventListener('touchmove', handleTouchMove);
document.removeEventListener('touchend', handleTouchEnd);
document.removeEventListener('gesturestart', handleGestureStart);

// 重新添加事件监听器
document.addEventListener('touchstart', handleTouchStart);
document.addEventListener('touchmove', handleTouchMove);
document.addEventListener('touchend', handleTouchEnd);
document.addEventListener('gesturestart', handleGestureStart);

// 添加撤销按钮的事件处理
function undo() {
  if (game) {
    game.undo();
  }
}

// 监听页面可见性变化
document.addEventListener('visibilitychange', () => {
  if (document.hidden && game) {
    game.saveGameState(); // 页面隐藏时保存状态
  }
});

// 监听页面关闭事件
window.addEventListener('beforeunload', () => {
  if (game) {
    game.saveGameState(); // 页面关闭前保存状态
  }
});

// 监听页面失去焦点事件
window.addEventListener('blur', () => {
  if (game) {
    game.saveGameState(); // 页面失去焦点时保存状态
  }
}); 